package com.sz.mes.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.S;
import com.diboot.core.vo.JsonResult;
import com.diboot.iam.entity.IamUser;
import com.diboot.iam.mapper.IamUserMapper;
import com.diboot.iam.util.IamSecurityUtils;
import com.sz.mes.dto.ClockInDTO;
import com.sz.mes.entity.*;
import com.sz.mes.mapper.*;
import com.sz.mes.service.ClockInService;
import com.sz.mes.service.impl.BaseCustomServiceImpl;
import com.sz.mes.vo.ClockInDetailVO;
import com.sz.mes.vo.GenerateTechniqueVO;
import com.sz.mes.vo.TechniqueDetailVO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collector;

/**
 * 上下机记录相关Service实现
 *
 * @author hem
 * @version 1.0
 * @date 2023-06-19
 * Copyright © szhs
 */
@Service
@Slf4j
public class ClockInServiceImpl extends BaseCustomServiceImpl<ClockInMapper, ClockIn> implements ClockInService {
    @Autowired
    private TechniqueMapper techniqueMapper;
    @Autowired
    private TechMapper techMapper;
    @Autowired
    private ClockInMapper clockInMapper;
    @Autowired
    private IamUserMapper iamUserMapper;
    @Autowired
    private ProductTaskMapper productTaskMapper;
    @Autowired
    private OutputMapper outputMapper;

    @Override
    public JsonResult generateTechnique(GenerateTechniqueVO generateTechniqueVO) {
        if (generateTechniqueVO.getTaskNum().equals("") && generateTechniqueVO.getTechName().equals("") && generateTechniqueVO.getEquipmentNumber().equals("")) {
            return JsonResult.FAIL_OPERATION("漏扫描，请重新扫描");
        }
        Long currentUserId = IamSecurityUtils.getCurrentUserId();
        IamUser iamUser = iamUserMapper.selectById(currentUserId);

        String workEquipment = generateTechniqueVO.getWorkEquipment();

        QueryWrapper<Tech> tqw = new QueryWrapper<>();
        tqw.eq("task_num", generateTechniqueVO.getTaskNum());
        tqw.eq("tech_name", generateTechniqueVO.getTechName());
        tqw.eq("id", generateTechniqueVO.getId());
        Tech tech = techMapper.selectOne(tqw);
        if (tech == null) {
            return JsonResult.FAIL_OPERATION("该任务单不存在此工艺");
        }

        QueryWrapper<Technique> techniqueQueryWrapper = new QueryWrapper<>();
        techniqueQueryWrapper.eq("task_num", generateTechniqueVO.getTaskNum());
        techniqueQueryWrapper.eq("tech_name", generateTechniqueVO.getTechName());
        techniqueQueryWrapper.eq("is_rework", 0);
        techniqueQueryWrapper.eq("work_equipment", generateTechniqueVO.getWorkEquipment());
        Technique technique = techniqueMapper.selectOne(techniqueQueryWrapper);

        //判断是否为返工工单
//        QueryWrapper<Tech> techQueryWrapper = new QueryWrapper<>();
//        techQueryWrapper.eq("task_num", generateTechniqueVO.getTaskNum());
//        List<Tech> techList = techMapper.selectList(techQueryWrapper);
//
//        QueryWrapper<Technique> tQueryWrapper = new QueryWrapper<>();
//        tQueryWrapper.eq("task_num", generateTechniqueVO.getTaskNum());
//        tQueryWrapper.eq("tech_name", techList.get(techList.size() - 1).getTechName());
//        tQueryWrapper.eq("is_rework", 0);
//        Technique rework = techniqueMapper.selectOne(tQueryWrapper);
//        int sum = 0;
//        if ( rework != null ){
//            QueryWrapper<Output> oQueryWrapper = new QueryWrapper<Output>()
//                    .eq("tech_id",rework.getId());
//            List<Output> outputs = outputMapper.selectList(oQueryWrapper);
//
//            if ( outputs.size() != 0 ){
//                sum = outputs.stream().map(Output::getBadQuantity).mapToInt(Integer::intValue).sum();
//            }
//        }

        if (technique == null ) {
            //如果实时工艺表没有该工艺，代表第一次生成工序任务
            //如果新增的工序任务，实际加工设备和扫码的不一样，工序单一样，则新建一个工序单
            Technique newTechnique = new Technique();
            newTechnique.setUserName(iamUser.getRealname());
            newTechnique.setTechId(tech.getId());
            newTechnique.setTechName(tech.getTechName());
            newTechnique.setTaskNum(tech.getTaskNum());
            newTechnique.setTechTime(tech.getTechTime());
            newTechnique.setEquipment(tech.getEquipment());
            newTechnique.setWorkEquipment(workEquipment);
            newTechnique.setIsUsed(1);
            newTechnique.setState(2);
            newTechnique.setStartTime(new Date());
            newTechnique.setIsChangeWork(generateTechniqueVO.getIsChangeWork());
            newTechnique.setOutput(0L);
            newTechnique.setGoodQuantity(0L);
            newTechnique.setBadQuantity(0L);
            newTechnique.setIsRework(0);
//            if ( rework != null && sum != 0){
//                newTechnique.setIsRework(1);
//            }else {
//
//            }
            int insert = techniqueMapper.insert(newTechnique);
            Long techniqueId = newTechnique.getId();
            //生成加工任务后上机
            ClockIn clockIn = new ClockIn();
            clockIn.setTaskNum(generateTechniqueVO.getTaskNum());
            clockIn.setEquipmentNumber(generateTechniqueVO.getWorkEquipment());
            clockIn.setTechName(generateTechniqueVO.getTechName());
            clockIn.setOperated(1);
            clockIn.setOutput(0L);
            //交班状态
            clockIn.setIsChangeWork(generateTechniqueVO.getIsChangeWork());

            clockIn.setTechniqueId(techniqueId);
            clockIn.setUserId(currentUserId);
            clockIn.setUserName(iamUser.getRealname());
            //        int i = clockInMapper.insert(clockIn);
            JsonResult upplane = this.upplane(clockIn);


            if ( insert == 1 && upplane.getCode() == 0 ) {
                return JsonResult.OK("生成工序任务成功");
            }else {
                return JsonResult.FAIL_EXCEPTION("生成失败");
            }
        }else if ( technique.getState() == 1 ){
            return JsonResult.FAIL_VALIDATION("任务已完成");
        }else {
            //交班，不同的人，在同一台设备对同一道工序进行生产
            HashMap<String, Long> hashMap = new HashMap<>();
            hashMap.put("id",technique.getId());
            String s = JSONObject.toJSONString(hashMap);

            return JsonResult.FAIL_OPERATION(s);
        }

//        else if ( technique != null && rework != null ){
//
//            QueryWrapper<Technique> queryWrapper = new QueryWrapper<>();
//            queryWrapper.eq("task_num", generateTechniqueVO.getTaskNum());
//            queryWrapper.eq("tech_name", generateTechniqueVO.getTechName());
//            queryWrapper.eq("is_rework", 1);
//            queryWrapper.eq("work_equipment", generateTechniqueVO.getWorkEquipment());
//            Technique techniqueO = techniqueMapper.selectOne(queryWrapper);
//            //返工
//            if ( techniqueO == null ){
//                Technique newTechnique = new Technique();
//                newTechnique.setUserName(iamUser.getRealname());
//                newTechnique.setTechId(tech.getId());
//                newTechnique.setTechName(tech.getTechName());
//                newTechnique.setTaskNum(tech.getTaskNum());
//                newTechnique.setTechTime(tech.getTechTime());
//                newTechnique.setEquipment(tech.getEquipment());
//                newTechnique.setWorkEquipment(workEquipment);
//                newTechnique.setIsUsed(1);
//                newTechnique.setState(2);
//                newTechnique.setStartTime(new Date());
//                newTechnique.setIsChangeWork(generateTechniqueVO.getIsChangeWork());
//                newTechnique.setOutput(0L);
//
//                if ( rework != null && sum != 0){
//                    newTechnique.setIsRework(1);
//                    int insert = techniqueMapper.insert(newTechnique);
//                    Long techniqueId = newTechnique.getId();
//                    //生成加工任务后上机
//                    ClockIn clockIn = new ClockIn();
//                    clockIn.setTaskNum(generateTechniqueVO.getTaskNum());
//                    clockIn.setEquipmentNumber(generateTechniqueVO.getWorkEquipment());
//                    clockIn.setTechName(generateTechniqueVO.getTechName());
//                    clockIn.setOperated(1);
//                    clockIn.setOutput(0L);
//                    //交班状态
//                    clockIn.setIsChangeWork(generateTechniqueVO.getIsChangeWork());
//
//                    clockIn.setTechniqueId(techniqueId);
//                    clockIn.setUserId(currentUserId);
//                    clockIn.setUserName(iamUser.getRealname());
//                    clockIn.setPid(0L);
//                    clockIn.setUserId(iamUser.getId());
//                    clockIn.setUserName(iamUser.getRealname());
//                    clockIn.setOutput(0L);
//                    clockIn.setIsChangeWork(clockIn.getIsChangeWork());
//                    boolean entity = super.createEntity(clockIn);
//
//                    if ( insert == 1 && entity ) {
//                        return JsonResult.OK("生成工序任务成功");
//                    }else {
//                        return JsonResult.FAIL_EXCEPTION("生成失败");
//                    }
//                }else {
//                    return JsonResult.FAIL_EXCEPTION("返工已存在");
//                }
//
//
//
//
//
//            }else {
//                return JsonResult.FAIL_EXCEPTION("无法返工");
//            }
//
//        }

    }


    /**
     * 上机
     *
     * @param clockIn
     * @return
     */
    @Override
    public JsonResult upplane(ClockIn clockIn) {
        QueryWrapper<Technique> tqw = new QueryWrapper<>();
        tqw.eq("task_num", clockIn.getTaskNum());
        tqw.eq("tech_name", clockIn.getTechName());
        tqw.eq("work_equipment", clockIn.getEquipmentNumber());
//        tqw.eq("tech_id", clockIn.getTechniqueId());
        Technique technique = techniqueMapper.selectOne(tqw);


        IamUser iamUser = iamUserMapper.selectById(IamSecurityUtils.getCurrentUserId());

        if (technique != null) {
            technique.setIsUsed(1);
//            technique.setIsChangeWork(clockIn.getIsChangeWork());
//            technique.setUserName(iamUser.getRealname());
//            technique.setStartTime(new Date());
        }
        int i = techniqueMapper.updateById(technique);

        clockIn.setPid(0L);
        clockIn.setUserId(iamUser.getId());
        clockIn.setUserName(iamUser.getRealname());
        clockIn.setOutput(0L);
        clockIn.setIsChangeWork(clockIn.getIsChangeWork());
        boolean entity = super.createEntity(clockIn);

        if ( entity && i == 1) {
            return JsonResult.OK("上机成功");
        } else {
            return JsonResult.FAIL_EXCEPTION("上机失败");
        }
    }

    /**
     * 下机
     *
     * @param clockIn
     * @return
     */
    @Override
    public JsonResult deplane(ClockInDTO clockIn) {
//        QueryWrapper<Technique> tqw = new QueryWrapper<>();
//        tqw.eq("task_num", clockIn.getTaskNum());
//        tqw.eq("tech_name", clockIn.getTechName());
//        tqw.eq("work_equipment", clockIn.getEquipmentNumber());
//        tqw.eq("tech_id", clockIn.getTechniqueId());
        Technique technique = techniqueMapper.selectById(clockIn.getTechniqueId());
        IamUser iamUser = iamUserMapper.selectById(IamSecurityUtils.getCurrentUserId());
//        if (technique != null) {
//            technique.setIsUsed(0);
//            if (technique.getOutput() == null) {
//                technique.setOutput(clockIn.getOutput());
//                technique.setUserName(iamUser.getRealname());
//            } else {
//                technique.setOutput(technique.getOutput() + clockIn.getOutput());
//            }
//        }
//        int i = techniqueMapper.updateById(technique);

        //同步产出
        //查本人这道工序上机的操作记录
        QueryWrapper<ClockIn> cqw = new QueryWrapper<ClockIn>()
                .eq("technique_id",technique.getId())
                .eq("user_name",iamUser.getRealname())
                .eq("operated",1);
//                .last("ORDER BY id DESC LIMIT 1");
//        ClockIn clockIn2 = clockInMapper.selectOne(cqw);
        List<ClockIn> upplane = clockInMapper.selectList(cqw);

        //查本人这道工序下机的操作记录
        QueryWrapper<ClockIn> dqw = new QueryWrapper<ClockIn>()
                .eq("technique_id",technique.getId())
                .eq("user_name",iamUser.getRealname())
                .eq("operated",0);
        List<ClockIn> deplane = clockInMapper.selectList(dqw);
//        ClockIn clockIn1 = clockInMapper.selectOne(dqw);

        int ins=0;
        if ( upplane.size() > 1 ){
            //当前下机时间在协调或交班人的上机时间之后
            QueryWrapper<ClockIn> eq1 = new QueryWrapper<ClockIn>()
                    .eq("technique_id",clockIn.getTechniqueId())
                    .eq("operated",1)
                    .gt("create_time",upplane.get(upplane.size()-1).getCreateTime());
            List<ClockIn> clockIns = clockInMapper.selectList(eq1);
            ins=clockIns.size();
        }


        //没有过这条上机记录对应的下机记录
        if ( deplane.size() == 0 && ins == 0 ) {
            if ( technique != null ){
                technique.setIsUsed(0);
            }
            technique.setGoodQuantity(technique.getGoodQuantity()+clockIn.getGoodQuantity());
            technique.setBadQuantity(technique.getBadQuantity()+clockIn.getBadQuantity());
            technique.setOutput(technique.getOutput()+clockIn.getOutput());
            int i = techniqueMapper.updateById(technique);

            clockIn.setPid(upplane.get(upplane.size()-1).getId());
            clockIn.setUserId(IamSecurityUtils.getCurrentUserId());
            clockIn.setUserName(iamUser.getRealname());
            clockIn.setOperated(0);
            clockIn.setIsChangeWork(clockIn.getIsChangeWork());
            clockIn.setTechniqueId(technique.getId());
            int insert = clockInMapper.insert(clockIn);
            if (i == 1 && insert == 1) {
                return JsonResult.OK("已下机");
            }
        }else if (ins != 0){
            return JsonResult.FAIL_OPERATION("超过固定生产时间，不能下机，请补卡");
        }else if ( deplane.size() != 0 && ins == 0 ) {
            if (technique != null) {
                technique.setIsUsed(0);
            }
            technique.setGoodQuantity(technique.getGoodQuantity()+clockIn.getGoodQuantity());
            technique.setBadQuantity(technique.getBadQuantity()+clockIn.getBadQuantity());
            technique.setOutput(technique.getOutput()+clockIn.getOutput());
            int i = techniqueMapper.updateById(technique);

            clockIn.setPid(upplane.get(upplane.size()-1).getId());
            clockIn.setUserId(IamSecurityUtils.getCurrentUserId());
            clockIn.setUserName(iamUser.getRealname());
            clockIn.setOperated(0);
            clockIn.setIsChangeWork(clockIn.getIsChangeWork());
            clockIn.setTechniqueId(technique.getId());
            int insert = clockInMapper.insert(clockIn);
            if (i == 1 && insert == 1) {
                return JsonResult.OK("已下机");
            }
        }
        return JsonResult.FAIL_EXCEPTION("下机失败");
    }


    /**
     * 完成
     *
     * @param clockIn
     * @return
     */
    @Override
    public JsonResult executeState(ClockIn clockIn) {
        QueryWrapper<Technique> tqw = new QueryWrapper<>();
//        tqw.eq("id",clockIn.getTechniqueId());
        tqw.eq("task_num", clockIn.getTaskNum());
        tqw.eq("tech_name", clockIn.getTechName());
        tqw.eq("work_equipment", clockIn.getEquipmentNumber());
        Technique technique = techniqueMapper.selectOne(tqw);

        //同步产出
//        QueryWrapper<ClockIn> oqw = new QueryWrapper<>();
//        oqw.eq("task_num",clockIn.getTaskNum());
//        oqw.last("ORDER BY create_time DESC LIMIT 1");
//        ClockIn clockIn1 = clockInMapper.selectOne(oqw);

        if (technique != null) {
            technique.setIsUsed(0);
            technique.setState(1);
            technique.setEndTime(new Date());
//            technique.setOutput(clockIn.getOutput() + technique.getOutput());
        }
        int i = techniqueMapper.updateById(technique);

        if (i != 0) {
            return JsonResult.OK("任务已完成");
        } else {
            return JsonResult.FAIL_EXCEPTION("任务无法正常完成");
        }
    }

    @Override
    public JsonResult findProductDetail(ClockIn clockIn) {
        QueryWrapper<ClockIn> wrapper = new QueryWrapper<ClockIn>()
                .eq("tech_name",clockIn.getTechName())
                .eq("task_num",clockIn.getTaskNum())
                .orderByDesc("create_time");
        List<ClockIn> clockIns = clockInMapper.selectList(wrapper);

        List<ClockInDetailVO> clockInDetailVOS = BeanUtils.convertList(clockIns, ClockInDetailVO.class);


        QueryWrapper<Technique> tqw = new QueryWrapper<Technique>()
                .eq("tech_name",clockIn.getTechName())
                .eq("task_num",clockIn.getTaskNum())
                .eq("work_equipment",clockIn.getEquipmentNumber());
        Technique technique = techniqueMapper.selectOne(tqw);

        QueryWrapper<ProductTask> pqw = new QueryWrapper<>();
        pqw.eq("task_num", clockIn.getTaskNum());
        List<ProductTask> productTaskList = productTaskMapper.selectList(pqw);
        ProductTask productTask = productTaskList.get(0);

        TechniqueDetailVO techniqueDetailVO = new TechniqueDetailVO();
        techniqueDetailVO.setTaskNum(clockIn.getTaskNum());
        techniqueDetailVO.setTaskName(productTask.getProductName());
        techniqueDetailVO.setQuantity(productTask.getQuantity());
        techniqueDetailVO.setClockInList(clockInDetailVOS);
        techniqueDetailVO.setTechName(clockIn.getTechName());
        techniqueDetailVO.setEquipment(technique.getWorkEquipment());
        techniqueDetailVO.setOutput(technique.getOutput());
        techniqueDetailVO.setBadQuantity(technique.getBadQuantity());
        techniqueDetailVO.setGoodQuantity(technique.getGoodQuantity());
        techniqueDetailVO.setIsRework(technique.getIsRework());
        return JsonResult.OK(techniqueDetailVO);
    }

    @Override
    public JsonResult findTaskList(Integer state) {
        ArrayList<Technique> list = new ArrayList<>();
        QueryWrapper<ClockIn> eq = new QueryWrapper<ClockIn>()
                .eq("user_id", IamSecurityUtils.getCurrentUserId());

        List<ClockIn> clockInList = clockInMapper.selectList(eq);
//        List<String> clockInList = clockInMapper.selectTaskNum(technique.getUserId());
        List<Long> list1 = new ArrayList<>();
        for (ClockIn clockIn:clockInList){
            if (!list1.contains(clockIn.getTechniqueId())){
                list1.add(clockIn.getTechniqueId());
            }
        }
        for (Long techniqueId:list1){
            QueryWrapper<Technique> qw = new QueryWrapper<Technique>()
                    .eq("id",techniqueId)
                    .eq("state",state)
                    .orderByDesc("create_time");
            List<Technique> techniqueList = techniqueMapper.selectList(qw);

            if (techniqueList!=null && techniqueList.size()!=0){
                for (Technique technique:techniqueList){
                    list.add(technique);
                }
            }
        }
        return JsonResult.OK(list);
    }

    @Override
    public Map<String, Object> getList(ClockInDTO clockInDTO) {
        HashMap<String, Object> map = new HashMap<>();
        QueryWrapper<ClockIn> pqw = new QueryWrapper<>();

        if (!StringUtils.isEmpty(clockInDTO.getUserName())){
            pqw.like("user_name",clockInDTO.getUserName());
        }
        if (!StringUtils.isEmpty(clockInDTO.getTaskNum())){
            pqw.like("task_num",clockInDTO.getTaskNum());
        }

        pqw.eq("is_deleted",0);
        Page<ClockIn> page = new Page<>(clockInDTO.getPageNumber(), clockInDTO.getPageSize());
        Page<ClockIn> ClockInPage = clockInMapper.selectPage(page, pqw);

        map.put("data",ClockInPage.getRecords());
        map.put("total",ClockInPage.getTotal());
        return map;
    }

}
